﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESPL.CodeGenerator.Common.Structs;
using ESPL.CodeGenerator.Common.Enums;
using ESPL.CodeGenerator.Domain.Utilities;
using ESPL.CodeGenerator.Domain.TemplateGenerators.ProjectGenerators;
using ESPL.CodeGenerator.Common;
using ESPL.CodeGenerator.Common.ProjectBuilders;
using ESPL.CodeGenerator.Domain.TemplateGenerators.EntitiesGenerator;

namespace ESPL.CodeGenerator.Domain.ProjectBuilders
{
    internal abstract class ProjectBuilderBase : CodeBuilderBase, IProjectBuilder
    {
        #region Declarations

        protected string _ttIncludeFileName = "EF6.Utility.CS.ttinclude";
        protected string _dataModal = "DataModel.edmx";
        protected string _projectConfigName = "projectConfig.ttinclude";
        protected ClassLibraryConfiguration _projectConfig;
        private string _guid = System.Guid.NewGuid().ToString();
        public IList<string> Entities { get; set; }

        #endregion

        #region Constructor

        public ProjectBuilderBase(ApplicationConfiguration config, ClassLibraryConfiguration projectConfig)
            : base(config)
        {
            _projectConfig = projectConfig;
            Entities = new List<string>();
        }

        #endregion

        #region Properties

        public ClassLibraryConfiguration ProjectConfig { get { return _projectConfig; } }

        public string ProjectName
        {
            get
            {
                return string.Format("{0}.{1}.{2}", Config.CompanyNameAbbrevation, Config.ApplicationName, ProjectConfig.Name);
            }
        }

        public string Guid
        {
            get { return _guid; }
        }

        #endregion

        #region Methods

        protected override string GetFilePath()
        {
            return FileHelper.CombinePath(GetDirectoryPath(), string.Format("{0}.{1}.{2}.csproj", Config.CompanyNameAbbrevation, Config.ApplicationName, ProjectConfig.Name));
        }

        protected override string GetDirectoryPath()
        {
            var appDirectoryPath = FileHelper.CombinePath(Config.DestinationPath, Config.ApplicationName);
            return FileHelper.CombinePath(appDirectoryPath, ProjectName);
        }

        protected override void InitGenerator()
        {
            switch (ProjectConfig.Version)
            {
                case ClassLibraryVersion.DotNetFourPointZero:
                    _generator = new ClassLibraryProjectGenerator4_0(Config, this);
                    break;
                case ClassLibraryVersion.DotNetFourPointFive:
                    _generator = new ClassLibraryProjectGenerator4_5(Config, this);
                    break;
                case ClassLibraryVersion.DotNetFourPointFivePointOne:
                    _generator = new ClassLibraryProjectGenerator4_5_1(Config, this);
                    break;
            }
        }

        public override IList<IBuilderResponse> InitializeProjectTree()
        {
            return base.InitializeProjectTree();
        }

        protected override void CreateRequiredDirectory()
        {
            base.CreateRequiredDirectory();
            var propertiesFolderPath = string.Format("{0}/Properties", GetDirectoryPath());
            DirectoryHelper.CreateDirectory(propertiesFolderPath);
            var assemblyInfoGenerator = new AssemblyInfoGenerator(this);
            FileHelper.CreateFile(string.Format("{0}/AssemblyInfo.cs", propertiesFolderPath), assemblyInfoGenerator.TransformText());
        }

        protected virtual void WriteProjectConfig()
        {
            var projectConfigGenerator = new ProjectConfigGenerator(this,_projectConfig);
            var filePath = string.Format("{0}/{1}", GetDirectoryPath(), _projectConfigName);
            WriteFileContents(filePath, projectConfigGenerator);
        }

        protected void DeleteProjectConfig()
        {
            DeleteFile(System.IO.Path.Combine(GetDirectoryPath(), _projectConfigName));
        }

        protected virtual void ProcessEdmxProject(string templateFile)
        {
            if (string.IsNullOrEmpty(templateFile)) return;

            var templateFilePath = string.Format(@"{0}\TemplateGenerators\EntitiesGenerator", this.Config.ResourceFolderPath);
            CopyFile(templateFile, templateFilePath);
            var ttIncludeFileNamePath = string.Format(@"{0}\Resources", this.Config.ResourceFolderPath);
            CopyFile(_ttIncludeFileName, ttIncludeFileNamePath);
            CopyFile(Config.EdmxFileName, Config.EdmxFilePath,_dataModal);

            string targetPath = GetDirectoryPath();
            string destFile = System.IO.Path.Combine(targetPath, templateFile);

            WriteProjectConfig();

            ProcessTransformation(destFile);
            DeleteFile(System.IO.Path.Combine(targetPath, templateFile));
            DeleteFile(System.IO.Path.Combine(targetPath, templateFile.Replace(".tt", ".cs")));
            DeleteFile(System.IO.Path.Combine(targetPath, _ttIncludeFileName));
            DeleteFile(System.IO.Path.Combine(targetPath, _dataModal));
            DeleteProjectConfig();
        }

        #endregion
    }
}
